#include "StdAfx.h"
#include "ListExpandElementUI.h"
#include "BlueRenderEngineUI.h"
#include "PaintManagerUI.h"
#include "TileLayoutUI.h"

CListExpandElementUI::CListExpandElementUI(void): m_bExpanded(false), m_cyExpanded(0), m_pContainer(NULL)
{
}

CListExpandElementUI::~CListExpandElementUI(void)
{
	delete m_pContainer;
}

LPCTSTR CListExpandElementUI::GetClass() const
{
	return _T("ListExpandElementUI");
}

bool CListExpandElementUI::Expand(bool bExpand)
{
	ASSERT(m_pOwner);
	if( m_pOwner == NULL ) return false;  
	if( bExpand == m_bExpanded ) return true;
	m_bExpanded = bExpand;
	if( !m_pOwner->ExpandItem(m_iIndex, bExpand) ) return false;
	// We need to manage the "expanding items", which are actually embedded controls
	// that we selectively display or not.
	if( bExpand ) 
	{
		delete m_pContainer;
		CTileLayoutUI* pTile = new CTileLayoutUI;
		pTile->SetPadding(4);
		m_pContainer = pTile;
		if( m_pManager != NULL ) m_pManager->SendNotify(this, _T("itemexpand"));
		m_pManager->InitControls(m_pContainer, this);
	}
	else
	{
		if( m_pManager != NULL ) m_pManager->SendNotify(this, _T("itemcollapse"));
	}
	m_cyExpanded = 0;
	return true;
}

bool CListExpandElementUI::IsExpanded() const
{
	return m_bExpanded;
}

void CListExpandElementUI::Event(TEventUI& event)
{
	if( event.Type == UIEVENT_BUTTONUP )
	{
		if( m_pOwner == NULL ) return;
		const TListInfoUI* pInfo = m_pOwner->GetListInfo();
		RECT rcExpander = { m_rcItem.left, m_rcItem.top, m_rcItem.left + 20, m_rcItem.bottom };;
		if( pInfo->bExpandable && ::PtInRect(&rcExpander, event.ptMouse) ) Expand(!m_bExpanded);
	}
	if( event.Type == UIEVENT_KEYDOWN )
	{
		switch( event.chKey ) {
	  case VK_LEFT:
		  Expand(false);
		  return;
	  case VK_RIGHT:
		  Expand(true);
		  return;
		}
	}
	CListTextElementUI::Event(event);
}

SIZE CListExpandElementUI::EstimateSize(SIZE szAvailable)
{
	if( m_pOwner == NULL ) return CStdSize();
	// We calculate the item height only once, because it will not wrap on the
	// line anyway when the screen is resized.
	if( m_cyItem == 0 ) {
		LPCTSTR pstrText = _T("XXX");
		RECT rcText = { 0, 0, 9999, 9999 };
		int nLinks = 0;
		CBlueRenderEngineUI::DoPaintPrettyText(m_pManager->GetPaintDC(), m_pManager, rcText, pstrText, UICOLOR__INVALID, UICOLOR__INVALID, NULL, nLinks, DT_CALCRECT | m_uTextStyle);
		m_cyItem = (rcText.bottom - rcText.top) + 8;
	}
	int cyItem = m_cyItem;
	if( m_bExpanded && m_cyExpanded == 0 && m_pContainer != NULL && m_pContainer->GetCount() > 0 ) {
		RECT rcItem = m_pContainer->GetItem(0)->GetPos();
		// HACK: Here we boldy assume that the item height is the same as the listitem.
		m_cyExpanded = ((rcItem.bottom - rcItem.top) + 14) * ((m_pContainer->GetCount() + 1) / 2);
		m_cyExpanded += 4 * ((m_pContainer->GetCount() - 1) / 2);
		m_cyExpanded += 26;
	}
	return CStdSize(m_cxWidth, cyItem + m_cyExpanded + 1);
}

void CListExpandElementUI::SetPos(RECT rc)
{
	if( m_pContainer != NULL ) {
		RECT rcSubItems = { rc.left + 14, rc.top + m_cyItem, rc.right - 8, rc.bottom - 6 };
		m_pContainer->SetPos(rcSubItems);
	}
	CListTextElementUI::SetPos(rc);
}

bool CListExpandElementUI::Add(CControlUI* pControl)
{
	ASSERT(m_pContainer);
	if( m_pContainer == NULL ) return false;
	return m_pContainer->Add(pControl);
}

bool CListExpandElementUI::Remove(CControlUI* pControl)
{
	ASSERT(!"Not supported yet");
	return false; 
}

void CListExpandElementUI::RemoveAll()
{
	if( m_pContainer != NULL ) m_pContainer->RemoveAll();
}

CControlUI* CListExpandElementUI::GetItem(int iIndex) const
{
	if( m_pContainer == NULL ) return NULL;
	return m_pContainer->GetItem(iIndex);
}

int CListExpandElementUI::GetCount() const
{
	if( m_pContainer == NULL ) return 0;
	return m_pContainer->GetCount();
}

void CListExpandElementUI::DoPaint(HDC hDC, const RECT& rcPaint)
{
	CListTextElementUI::DoPaint(hDC, rcPaint);
	// Paint the expanded items?
	if( m_bExpanded && m_pContainer != NULL ) {
		// Paint gradient box for the items
		RECT rcFrame = m_pContainer->GetPos();
		COLORREF clr1, clr2;
		m_pManager->GetThemeColorPair(UICOLOR_CONTROL_BACKGROUND_EXPANDED, clr1, clr2);
		CBlueRenderEngineUI::DoPaintGradient(hDC, m_pManager, rcFrame, clr1, clr2, true, 64);
		CBlueRenderEngineUI::DoPaintRectangle(hDC, m_pManager, rcFrame, UICOLOR_HEADER_BORDER, UICOLOR__INVALID);
		RECT rcLine = { m_rcItem.left, rcFrame.top, m_rcItem.right, rcFrame.top };
		CBlueRenderEngineUI::DoPaintLine(hDC, m_pManager, rcLine, UICOLOR_STANDARD_BLACK);
		// We'll draw the items then...
		m_pContainer->DoPaint(hDC, rcPaint);
	}
}

void CListExpandElementUI::SetManager(CPaintManagerUI* pManager, CControlUI* pParent)
{
	if( m_pContainer != NULL ) m_pContainer->SetManager(pManager, pParent);
	CListTextElementUI::SetManager(pManager, pParent);
}

CControlUI* CListExpandElementUI::FindControl(FINDCONTROLPROC Proc, LPVOID pData, UINT uFlags)
{
	CControlUI* pResult = NULL;
	if( m_pContainer != NULL ) pResult = m_pContainer->FindControl(Proc, pData, uFlags);
	if( pResult == NULL ) pResult = CListTextElementUI::FindControl(Proc, pData, uFlags);
	return pResult;
}

void CListExpandElementUI::DrawItem(HDC hDC, const RECT& rcItem, UINT uStyle)
{
	ASSERT(m_pOwner);
	if( m_pOwner == NULL ) return;
	const TListInfoUI* pInfo = m_pOwner->GetListInfo();
	UITYPE_COLOR iTextColor = pInfo->Text;
	UITYPE_COLOR iBackColor = pInfo->Background;
	if( (m_uButtonState & UISTATE_HOT) != 0 ) {
		iBackColor = pInfo->HotBackground;
		iTextColor = pInfo->HotText;
	}
	if( IsSelected() ) {
		iTextColor = pInfo->SelText;
		iBackColor = pInfo->SelBackground;
	}
	if( !IsEnabled() ) {
		iTextColor = UICOLOR_CONTROL_TEXT_DISABLED;
		iBackColor = UICOLOR_CONTROL_BACKGROUND_DISABLED;
	}
	if( iBackColor != UICOLOR__INVALID ) {
		RECT rcItem = { m_rcItem.left, m_rcItem.top, m_rcItem.right, m_rcItem.top + m_cyItem };
		CBlueRenderEngineUI::DoFillRect(hDC, m_pManager, rcItem, iBackColor);
	}
	IListCallbackUI* pCallback = m_pOwner->GetTextCallback();
	ASSERT(pCallback);
	if( pCallback == NULL ) return;
	m_nLinks = 0;
	CStdString sColText;
	int nLinks = lengthof(m_rcLinks);
	for( int i = 0; i < pInfo->nColumns; i++ )
	{
		// Paint text
		RECT rcItem = { pInfo->rcColumn[i].left, m_rcItem.top, pInfo->rcColumn[i].right, m_rcItem.top + m_cyItem };
		LPCTSTR pstrText = pCallback->GetItemText(this, m_iIndex, i);
		// If list control is expandable then we'll automaticially draw
		// the expander-box at the first column.
		if( i == 0 && pInfo->bExpandable ) {
			sColText = (m_bExpanded ? _T("<i 14> ") : _T("<i 13> "));
			sColText += pstrText;
			pstrText = sColText;
		}
		::InflateRect(&rcItem, -4, 0);
		CBlueRenderEngineUI::DoPaintPrettyText(hDC, m_pManager, rcItem, pstrText, iTextColor, UICOLOR__INVALID, m_rcLinks, nLinks, DT_SINGLELINE | m_uTextStyle);
		if( nLinks > 0 ) m_nLinks = nLinks, nLinks = 0; else nLinks = lengthof(m_rcLinks);
	}
	RECT rcLine = { m_rcItem.left, m_rcItem.bottom - 1, m_rcItem.right, m_rcItem.bottom - 1 };
	CBlueRenderEngineUI::DoPaintLine(hDC, m_pManager, rcLine, UICOLOR_DIALOG_BACKGROUND);
}

